import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import 'package:encrypt/encrypt.dart';

/// AES加密工具类
/// 用于处理需要AES加密的API请求
class AESEncryption {
  // AES加密密钥 (32字节用于AES-256)
  static const String _secretKey = 'qwertyuiop1234567654zaqwsxcderfv';
  
  // 获取加密器
  static Encrypter get _encrypter {
    final key = Key.fromBase64(base64Encode(utf8.encode(_secretKey)));
    return Encrypter(AES(key, mode: AESMode.cbc));
  }

  /// 生成随机IV (16字节)
  static IV _generateRandomIV() {
    final random = Random.secure();
    final bytes = List<int>.generate(16, (_) => random.nextInt(256));
    return IV(Uint8List.fromList(bytes));
  }

  /// 生成验证码（支持特定手机号固定验证码）
  /// [phone] 手机号，用于判断是否需要返回固定验证码
  static String generateVerificationCode({String? phone}) {
    // 对于特定测试手机号，返回固定验证码
    if (phone == '19999999999') {
      return '888888';
    }
    
    // 其他手机号生成随机验证码
    final random = Random();
    final code = (100000 + random.nextInt(900000)).toString();
    return code;
  }

  /// 加密数据
  /// [data] 要加密的数据对象
  /// [includeTimestamp] 是否包含时间戳防重放攻击
  static String encryptData(Map<String, dynamic> data, {bool includeTimestamp = true}) {
    try {
      // 创建数据副本，避免修改原始数据
      final dataToEncrypt = Map<String, dynamic>.from(data);
      
      // 添加时间戳防重放攻击
      if (includeTimestamp) {
        dataToEncrypt['timestamp'] = (DateTime.now().millisecondsSinceEpoch / 1000).round();
      }

      // 转换为JSON字符串
      final jsonString = jsonEncode(dataToEncrypt);
      
      // 生成随机IV
      final iv = _generateRandomIV();
      
      // 加密数据
      final encrypted = _encrypter.encrypt(jsonString, iv: iv);
      
      // 将IV和加密数据合并（IV在前16字节）
      final combined = Uint8List(16 + encrypted.bytes.length);
      combined.setRange(0, 16, iv.bytes);
      combined.setRange(16, combined.length, encrypted.bytes);
      
      // 返回Base64编码的结果
      return base64Encode(combined);
    } catch (e) {
      print('💥 encryptData详细错误: $e');
      print('💥 错误堆栈: ${StackTrace.current}');
      throw Exception('AES加密失败: $e');
    }
  }

  /// 解密数据（主要用于调试验证）
  /// [encryptedData] Base64编码的加密数据
  static Map<String, dynamic> decryptData(String encryptedData) {
    try {
      // Base64解码
      final combined = base64Decode(encryptedData);
      
      // 提取IV（前16字节）
      final ivBytes = combined.sublist(0, 16);
      final iv = IV(ivBytes);
      
      // 提取加密数据（16字节之后）
      final encryptedBytes = combined.sublist(16);
      final encrypted = Encrypted(encryptedBytes);
      
      // 解密
      final decrypted = _encrypter.decrypt(encrypted, iv: iv);
      
      // 解析JSON
      return jsonDecode(decrypted);
    } catch (e) {
      throw Exception('AES解密失败: $e');
    }
  }

  /// 验证时间戳是否有效（5分钟内）
  static bool isTimestampValid(int timestamp) {
    final now = (DateTime.now().millisecondsSinceEpoch / 1000).round();
    final diff = now - timestamp;
    return diff >= 0 && diff <= 300; // 5分钟 = 300秒
  }

  /// 生成带时间戳的加密验证码请求
  static String encryptSmsRequest({
    required String userPhone,
    required String userCode,
  }) {
    try {
      final data = <String, dynamic>{
        'userPhone': userPhone.toString(),
        'userCode': userCode.toString(),
      };
      
      // 调试信息
      // print('🔍 准备加密的数据: $data');
      
      return encryptData(data, includeTimestamp: true);
    } catch (e) {
      print('💥 encryptSmsRequest异常: $e');
      rethrow;
    }
  }

  /// 验证解密后的数据完整性
  static bool validateDecryptedData(Map<String, dynamic> data, {
    required String expectedPhone,
    required String expectedCode,
  }) {
    try {
      // 检查必要字段
      if (!data.containsKey('userPhone') || 
          !data.containsKey('userCode') || 
          !data.containsKey('timestamp')) {
        return false;
      }

      // 验证手机号
      if (data['userPhone'] != expectedPhone) {
        return false;
      }

      // 验证验证码
      if (data['userCode'] != expectedCode) {
        return false;
      }

      // 验证时间戳
      final timestamp = data['timestamp'] as int;
      if (!isTimestampValid(timestamp)) {
        return false;
      }

      return true;
    } catch (e) {
      return false;
    }
  }
}
